﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using coffeeshop.Models;
using System.Globalization;

namespace coffeeshop.Forms
{
    public partial class frmEditProduct : Form
    {
        private Product theObject { get; set; }
        private List<ProductIngredient> theIngredients { get; set; }

        private coffeeDataSet.UnitDataTable unitList { get; set; }
        private coffeeDataSet.ProductCategoryDataTable categoryList { get; set; }
        private coffeeDataSet.ProductDataTable productList { get; set; }

        private bool hasCheckedQuantity;

        public Form MyParentForm { get; set; }

        private const string COLUMN_NAME_TT = "TT";
        private const string COLUMN_NAME_TEN = "Tên";
        private const string COLUMN_NAME_SL = "SL";
        private const string COLUMN_NAME_DL = "ĐL";

        public frmEditProduct(Product _object)
        {
            InitializeComponent();

            LoadUnits();
            LoadCategories();
            LoadProducts();
            LoadIngredientDatagrid();

            if (_object != null)
            {
                theObject = _object;
                LoadObjectInfo();

                LoadProductIngredients();
            }
            else
                LoadDataGridViewDefaultRow();
        }

        private void LoadCategories()
        {
            categoryList = ProductCategory.LoadCategories(true);
            cboCategoryId.DataSource = categoryList;
            cboCategoryId.DisplayMember = "Name";
            cboCategoryId.ValueMember = "ProductCategoryId";
        }

        private void LoadDataGridViewDefaultRow()
        { 
            // Load default row for empty ingredient
        }
        // TODO, don't load the product itself in the combobox ingredient for that compound product
        private void LoadProductIngredients()
        {
            if (theObject.CompoundProductId != null && theObject.CompoundProductId > 0)
            {
                radioCompose.Checked = true;
                SetGridEnable(true);

                List<ProductIngredient> _list = ProductIngredient.GetProductIngredients(theObject.ProductId);
                if (_list.Any())
                {
                    foreach (ProductIngredient pi in _list)
                    {
                        DataGridViewRow dataRow = (DataGridViewRow)dataGridView1.Rows[0].Clone();
                        dataRow.Cells[0].Value = pi.ProductId;
                        dataRow.Cells[1].Value = pi.Quantity;
                        dataRow.Cells[2].Value = pi.UnitName;

                        dataGridView1.Rows.Add(dataRow);
                    }
                }
            }
        }

        private void SetGridEnable(bool toEnable)
        {
            if (toEnable)
            {
                dataGridView1.ForeColor = Color.Black;
                dataGridView1.ColumnHeadersDefaultCellStyle.ForeColor = Color.Black;
                dataGridView1.EnableHeadersVisualStyles = true;
                dataGridView1.ReadOnly = false; 
            }
            else
            {
                dataGridView1.ForeColor = Color.DarkGray;
                dataGridView1.ColumnHeadersDefaultCellStyle.ForeColor = Color.DarkGray;
                dataGridView1.EnableHeadersVisualStyles = false;
                dataGridView1.ReadOnly = true;
            }
        }

        private void LoadIngredientDatagrid()
        {
            SetGridEnable(false);

            DataGridViewComboBoxColumn cmbName = new DataGridViewComboBoxColumn();
            cmbName.HeaderText = COLUMN_NAME_TEN;
            cmbName.Name = "cmbName";
            cmbName.DataSource = productList;
            cmbName.AutoComplete = true;
            cmbName.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            cmbName.DisplayMember = "Name";
            cmbName.ValueMember = "ProductId";
            dataGridView1.Columns.Add(cmbName);

            DataGridViewTextBoxColumn txtQuantity = new DataGridViewTextBoxColumn();
            txtQuantity.HeaderText = COLUMN_NAME_SL;
            txtQuantity.Name = "txtQuantity";
            dataGridView1.Columns.Add(txtQuantity);

            DataGridViewTextBoxColumn txtUnit = new DataGridViewTextBoxColumn();
            txtUnit.HeaderText = COLUMN_NAME_DL;
            txtUnit.Name = "txtUnit";
            dataGridView1.Columns.Add(txtUnit);

            dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            dataGridView1.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            dataGridView1.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

            dataGridView1.Columns[0].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
            dataGridView1.Columns[1].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
            dataGridView1.Columns[2].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;

            dataGridView1.Columns[0].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
            dataGridView1.Columns[1].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            dataGridView1.Columns[2].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;

            dataGridView1.Columns[2].ReadOnly = true;
            dataGridView1.Columns[2].DefaultCellStyle.ForeColor = Color.DarkGray;
        }

        private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {
            if (dataGridView1.CurrentCell.ColumnIndex == 0 && e.Control is ComboBox)
            {
                ComboBox comboBox = e.Control as ComboBox;
                comboBox.AutoCompleteSource = AutoCompleteSource.ListItems;
                
                comboBox.AutoCompleteMode = AutoCompleteMode.Append;
                comboBox.DropDownStyle = ComboBoxStyle.DropDownList;
                comboBox.SelectedIndexChanged += LastColumnComboSelectionChanged;
            }

            else if (dataGridView1.CurrentCell.ColumnIndex == 1 && e.Control is TextBox)
            {
                TextBox textBox = e.Control as TextBox;
                textBox.KeyPress += new KeyPressEventHandler(textBox_KeyPress);
                textBox.LostFocus += new EventHandler(textBox_LostFocus);
            }
        }

        void textBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            hasCheckedQuantity = false;
        }

        void textBox_LostFocus(object sender, EventArgs e)
        {
            if (hasCheckedQuantity)
                return;

            bool isPassed = true;
            string msg = string.Empty;
            TextBox theTextBox = (TextBox)sender;
            if (string.IsNullOrEmpty(theTextBox.Text.Trim()))
            {
                isPassed = false;
                msg = "Xin nhập số lượng cho thành phần này";
                
            }
            float quantity;
            if (!float.TryParse(theTextBox.Text.Trim(), out quantity) || quantity <= 0)
            {
                isPassed = false;
                msg = "Xin nhập số thập phân hợp lệ và lớn hơn 0. Dấu thập phân là dấu CHẤM (.)";
                
            }
            hasCheckedQuantity = true;

            if (!isPassed)
            {
                // deu hieu sao ko hoat dong
                //sendingTextBox.ForeColor = Color.Red;
                //dataGridView1.CurrentCell = quantityCell;
                //dataGridView1.CurrentCell.Selected = true;
                //dataGridView1.BeginEdit(true);
                MessageBox.Show(msg);
            }
            else
            {
                //sendingTextBox.ForeColor = Color.Black;
            }
        }

        private void LastColumnComboSelectionChanged(object sender, EventArgs e)
        {
            var currentcell = dataGridView1.CurrentCellAddress;
            var sendingCB = sender as DataGridViewComboBoxEditingControl;
            DataGridViewTextBoxCell unitCell = (DataGridViewTextBoxCell)dataGridView1.Rows[currentcell.Y].Cells[2];
            int productId;
            int.TryParse(sendingCB.SelectedValue == null ? string.Empty : sendingCB.SelectedValue.ToString(), out productId);
            unitCell.Value = GetUnitNameByProductId(productId);

            // TODO: move to edit the price
            //DataGridViewTextBoxCell priceCell = (DataGridViewTextBoxCell)dataGridView1.Rows[currentcell.Y].Cells[1];
            //dataGridView1.CurrentCell = priceCell;
            //dataGridView1.BeginEdit(true);
        }

        private string GetUnitNameByProductId(int productId)
        {
            if (productId == 0) return string.Empty;

            return productList.Where(u => u.ProductId == productId).Select(t => t.UnitName).First().ToString();
        }

        public void addNameItems(AutoCompleteStringCollection col)
        {
            foreach (DataRow row in productList.Rows)
            {
                col.Add(row["Name"].ToString());
            }
        }

        private void LoadUnits()
        {
            unitList = Unit.LoadUnits(true);
            cboUnit.DataSource = unitList;
            cboUnit.DisplayMember = "Name";
            cboUnit.ValueMember = "UnitId";
        }

        private void LoadProducts()
        {
            productList = Product.GetProductList(true);
        }

        private void LoadObjectInfo()
        {
            if (theObject != null)
            {
                theObject = Product.GetById(theObject.ProductId);
                txtName.Text = theObject.Name;
                txtCode.Text = theObject.Code;
                txtPrice.Text = theObject.Price.ToString();
                //string.Format(System.Globalization.CultureInfo.GetCultureInfo("vi-VN"), "{0:#,##0}", theObject.Price);
                cboUnit.SelectedValue = theObject.UnitId;

                cboCategoryId.SelectedValue = theObject.ProductCategoryId;
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            if (!InputsValidated())
                return;

            if (theObject == null)
                theObject = new Product();
            theObject.Name = txtName.Text.Trim();
            theObject.Code = txtCode.Text.Trim();
            theObject.Price = int.Parse(txtPrice.Text.Trim());
            theObject.UnitId = (int)cboUnit.SelectedValue;
            theObject.ProductCategoryId = (int)cboCategoryId.SelectedValue;

            if (!radioCompose.Checked)
            {
                theObject.CompoundProductId = null;
            }
            else
            {
                if (!SetProductIngredients())
                {
                    return;
                }
                if (theIngredients.Count < 2)
                {
                    var confirmResult = MessageBox.Show("Có quá ít thành phần để pha chế món này. Bạn có muốn lưu?",
                        "Xác nhận",
                        MessageBoxButtons.YesNo);
                    if (confirmResult != DialogResult.Yes)
                    {
                        return;
                    }
                }
            }

            if (!NameAndCodeValidated())
                return;

            if (theObject.Save())
            {
                if (radioCompose.Checked && !SaveProductIngredients())
                {
                    return;
                }
                

                this.Close();
                frmProductList listForm = (frmProductList)MyParentForm;
                listForm.ReloadList();
            }
            else
            {
                MessageBox.Show("Có lỗi khi lưu mặt hàng");
                return;
            }
        }

        private bool SaveProductIngredients()
        {
            // prepare to save product ingredient and compound product
            CompoundProduct cp = CompoundProduct.AddCompoundProduct();
            if (cp == null)
            {
                MessageBox.Show("Có lỗi khi tạo công thức pha chế");
                return false;
            }
            theObject.CompoundProductId = cp.CompoundProductId;
            if (!theObject.Save())
            {
                MessageBox.Show("Có lỗi khi gắn công thức pha chế vào mặt hàng");
                return false;
            }

            // lưu thành phần công thức
            try
            {
                for (int i = 0; i < theIngredients.Count; i++)
                {
                    ProductIngredient pi = theIngredients[i];
                    pi.CompoundProductId = (int)theObject.CompoundProductId;
                    pi.ForProductId = theObject.ProductId;
                    pi.Save();

                    theIngredients[i] = pi; // Update back the PrimaryKey
                }
            }
            catch
            {
                return false;
            }

            return true;
        }

        private bool SetProductIngredients() 
        {
            ProductIngredient pi;
            DataGridViewComboBoxCell idCell;
            DataGridViewTextBoxCell quantityCell;
            theIngredients = new List<ProductIngredient>();

            foreach (DataGridViewRow row in dataGridView1.Rows)
            {
                idCell = (DataGridViewComboBoxCell)row.Cells[0];
                quantityCell = (DataGridViewTextBoxCell)row.Cells[1];

                if (idCell.Value == null)
                    continue;

                if (quantityCell.Value == null)
                {
                    dataGridView1.ClearSelection();
                    quantityCell.Selected = true;
                    MessageBox.Show("Bạn chưa nhập số lượng cho thành phần");
                    return false;
                }

                pi = new ProductIngredient();
                pi.ProductId = (int)idCell.Value;

                if (theIngredients.Where(t => t.ProductId == pi.ProductId).Any())
                {
                    dataGridView1.ClearSelection();
                    idCell.Selected = true;
                    MessageBox.Show(string.Format("Bạn đã chọn thành phần({0}) này rồi.", idCell.EditedFormattedValue));
                    return false;
                }
                
                pi.Quantity = float.Parse(quantityCell.Value.ToString());
                theIngredients.Add(pi);
            }

            return true;
        }

        private bool NameAndCodeValidated()
        {
            Product product = Product.GetByNameAndCode(theObject.Name, theObject.Code);
            if (product.ProductId > 0) // there is 1 existing product having the code
            {
                if (theObject.ProductId == 0 || // create new: there is existing product having the code
                    theObject.ProductId != product.ProductId) // update: 2 objects have the same code
                {
                    MessageBox.Show("Tên hoặc mã viết tắt đã được dùng. Xin đổi tên hoặc mã khác");
                    return false;
                }
            }

            return true;
        }

        private bool InputsValidated()
        {
            if (string.IsNullOrEmpty(txtName.Text.Trim()))
            {
                MessageBox.Show("Cần điền tên mặt hàng");
                return false;
            }

            if (string.IsNullOrEmpty(txtCode.Text.Trim()))
            {
                MessageBox.Show("Cần điền mã viết tắt của mặt hàng");
                return false;
            }

            if (cboCategoryId.SelectedValue == null)
            {
                MessageBox.Show("Nhóm hàng không đúng");
                return false;
            }

            if ((int)cboCategoryId.SelectedValue == -1)
            {
                MessageBox.Show("Chưa chọn nhóm hàng");
                return false;
            }

            if (cboUnit.SelectedValue == null)
            {
                MessageBox.Show("Định lượng không đúng");
                return false;
            }

            

            if (string.IsNullOrEmpty(txtPrice.Text.Trim()))
            {
                MessageBox.Show("Cần điền giá. Nếu mặt hàng không bán, có thể nhập 0");
                return false;
            }

            int price;
            if (!int.TryParse(txtPrice.Text.Trim(), out price) || price < 0)
            {
                MessageBox.Show("Giá tiền không hợp lệ");
                return false;
            }

            return true;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void radioCompose_CheckedChanged(object sender, EventArgs e)
        {
            SetGridEnable((sender as RadioButton).Checked);
        }

        private void cboUnit_Leave(object sender, EventArgs e)
        {
            Console.Write("lost focus");
            int matchedIndex = cboUnit.FindString(((ComboBox)sender).Text);
            if (matchedIndex >= 0)
            {
                cboUnit.SelectedIndex = matchedIndex;
            }
            else
            {
                MessageBox.Show("Định lượng không đúng");
            }
        }

        private void cboCategoryId_Leave(object sender, EventArgs e)
        {
            Console.Write("lost focus");
            int matchedIndex = cboCategoryId.FindString(((ComboBox)sender).Text);
            if (matchedIndex >= 0)
            {
                cboCategoryId.SelectedIndex = matchedIndex;
            }
            else
            {
                MessageBox.Show("Nhóm hàng không đúng");
            }
        }

        private void dataGridView1_CellStateChanged(object sender, DataGridViewCellStateChangedEventArgs e)
        {
            if (e.Cell == null || e.StateChanged != DataGridViewElementStates.Selected)
                return;
            //this condition is necessary if you want to reset your DataGridView
            if (!e.Cell.Selected)
                return;
            
            if (e.Cell.ColumnIndex == 2) // unit column
            { 
                SendKeys.Send("{TAB}");
            }
        }
    }
}
